package com.example.kaogong.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.kaogong.common.utils.RespBean;
import com.example.kaogong.sys.mapper.*;
import com.example.kaogong.sys.pojo.Paper;
import com.example.kaogong.sys.pojo.PaperQuestion;
import com.example.kaogong.sys.pojo.Teacher;
import com.example.kaogong.sys.pojo.User;
import com.example.kaogong.sys.pojo.dto.PaperDto;
import com.example.kaogong.sys.pojo.dto.PaperQuestionDto;
import com.example.kaogong.sys.pojo.vo.PaperDetailInfoVo;
import com.example.kaogong.sys.pojo.vo.PaperInfoVo;
import com.example.kaogong.sys.pojo.vo.PaperQuestionVo;
import com.example.kaogong.sys.service.IPaperQuestionService;
import com.example.kaogong.sys.service.IPaperService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 试卷 服务实现类
 * </p>
 *
 * @author    
 * @since 2022-03-26
 */
@Service
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements IPaperService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private PaperMapper paperMapper;

    @Autowired
    private PaperQuestionMapper paperQuestionMapper;

    @Autowired
    private IPaperQuestionService paperQuestionService;

    @Autowired
    private OptionMapper optionMapper;

    /**
     * 教师创建试卷
     * @param paperDto
     * @param name
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RespBean createPaper(PaperDto paperDto, String name) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", name));
        if (user == null || user.getRoleId() != 2)
            return RespBean.error("创建试卷失败，权限不足");
        Teacher teacher = teacherMapper.selectOne(new QueryWrapper<Teacher>().eq("uid", user.getUid()).eq("deleted", false));
        if (teacher == null)
            return RespBean.error("创建试卷失败， 教师不存在或已被封禁");

        // 创建试卷并插入
        Paper paper = new Paper();
        paper.setPaperName(paperDto.getPaperName());
        paper.setTeacherId(teacher.getTeacherId());
        paper.setTestTime(paperDto.getTestTime());
        paper.setCreateTime(LocalDateTime.now());
        paper.setPaperType(paperDto.getPaperType());
        if (paperDto.getPaperQuestionDtoList() != null || paperDto.getPaperQuestionDtoList().size() > 0)
            paper.setPaperStatus(paperDto.getPaperStatus());
        else
            paper.setPaperStatus(1);

        int insert = paperMapper.createPaper(paper);
        if (insert < 1)
            return RespBean.error("创建试卷失败");

        // 插入试卷题目集合
        if (paperDto.getPaperQuestionDtoList() != null || paperDto.getPaperQuestionDtoList().size() > 1) {
            boolean insertQuestionList = this.insertQuestionIdList(paperDto.getPaperQuestionDtoList(), paper.getPaperId());
            if (!insertQuestionList) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return RespBean.error("创建试卷失败");
            }
        }
        return RespBean.success();
    }

    // 插入试卷题目编号
    private boolean insertQuestionIdList(List<PaperQuestionDto> paperQuestionDtoList, Integer paperId) {
        List<PaperQuestion> paperQuestionList = new ArrayList<>();
        paperQuestionDtoList.forEach(paperQuestionDto -> {
            PaperQuestion paperQuestion = new PaperQuestion();
            paperQuestion.setQuestionId(paperQuestionDto.getQuestionId());
            paperQuestion.setPaperId(paperId);
            paperQuestionList.add(paperQuestion);
        });
        return paperQuestionService.saveBatch(paperQuestionList);
    }

    /**
     * 添加试卷题目
     * @param paperQuestionDtoList
     * @param paperId
     * @return
     */
    @Override
    public RespBean addPaperQuestion(List<PaperQuestionDto> paperQuestionDtoList, Integer paperId) {
        Paper paper = paperMapper.selectOne(new QueryWrapper<Paper>().eq("paper_id", paperId));
        if (paper == null || paper.getPaperStatus() != 1)
            return RespBean.error();
        boolean insertQuestionIdList = insertQuestionIdList(paperQuestionDtoList, paperId);
        if (insertQuestionIdList)
            return RespBean.success();
        return RespBean.error();
    }

    /**
     * 删除试卷题目
     * @param paperQuestionDtoList
     * @param paperId
     * @return
     */
    @Override
    public RespBean deletePaperQuestion(List<PaperQuestionDto> paperQuestionDtoList, Integer paperId) {
        Paper paper = paperMapper.selectOne(new QueryWrapper<Paper>().eq("paper_id", paperId));
        if (paper == null || paper.getPaperStatus() != 1)
            return RespBean.error();
        for (PaperQuestionDto paperQuestionDto : paperQuestionDtoList) {
            int update = paperQuestionMapper.delete(new QueryWrapper<PaperQuestion>().eq("paper_id", paperId)
                                                        .eq("question_id", paperQuestionDto.getQuestionId()));

            if (update < 1)
                return RespBean.error();
        }
        return RespBean.success();
    }

    /**
     * 获取所有已发布试卷的基本信息
     * @return
     */
    @Override
    public RespBean<List<PaperInfoVo>> getAllPublishedPaper() {
        List<PaperInfoVo> paperInfoVoList = paperMapper.getAllPaperInfo(2, null);
        return RespBean.success(paperInfoVoList);
    }

    /**
     * 获取当前教师所有草稿试卷
     * @return
     * @param name
     */
    @Override
    public RespBean<List<PaperInfoVo>> getTeacherAllPaper(String name, int status) {
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", name));
        if (user == null || user.getRoleId() != 2)
            return RespBean.error("权限不足");
        Teacher teacher = teacherMapper.selectOne(new QueryWrapper<Teacher>().eq("uid", user.getUid()).eq("deleted", false));
        if (teacher == null)
            return RespBean.error("权限不足");
        List<PaperInfoVo> paperInfoVoList = paperMapper.getAllPaperInfo(status, teacher.getTeacherId());
        return RespBean.success(paperInfoVoList);
    }

    /**
     * 根据试卷编号获取试卷详细信息
     * @param paperId
     * @return
     */
    @Override
    public RespBean<PaperDetailInfoVo> getPaperDetailInfoById(Integer paperId) {
        PaperInfoVo paperInfoVo = paperMapper.getPaperInfo(paperId);

        // 单选题
        List<PaperQuestionVo> singleChoice = paperQuestionMapper.getQuestionListByPaperIdAndTypeId(paperId, 1);
        singleChoice.forEach(question -> {
            question.setOptionVoList(optionMapper.selectOptionVoListByQuestionId(question.getQuestionId()));
        });

        // 多选题
        List<PaperQuestionVo> multipleChoice = paperQuestionMapper.getQuestionListByPaperIdAndTypeId(paperId, 2);
        multipleChoice.forEach(question -> {
            question.setOptionVoList(optionMapper.selectOptionVoListByQuestionId(question.getQuestionId()));
        });

        //判断题
        List<PaperQuestionVo> judgement = paperQuestionMapper.getQuestionListByPaperIdAndTypeId(paperId, 3);

        //填空题
        List<PaperQuestionVo> fillBlank = paperQuestionMapper.getQuestionListByPaperIdAndTypeId(paperId, 4);

        //论述题
        List<PaperQuestionVo> essay = paperQuestionMapper.getQuestionListByPaperIdAndTypeId(paperId, 5);

        PaperDetailInfoVo paperDetailInfoVo = new PaperDetailInfoVo();
        paperDetailInfoVo.setPaperInfoVo(paperInfoVo);
        paperDetailInfoVo.setSingleChoice(singleChoice);
        paperDetailInfoVo.setMultipleChoice(multipleChoice);
        paperDetailInfoVo.setJudgment(judgement);
        paperDetailInfoVo.setFillBlank(fillBlank);
        paperDetailInfoVo.setEssay(essay);
        return RespBean.success(paperDetailInfoVo);
    }

    @Override
    public RespBean deletePaperById(Integer paperId) {
        int row = paperMapper.deletePaperById(paperId);
        if (row < 1)
            return RespBean.error();
        return RespBean.success();
    }

    @Override
    public RespBean publishPaperById(Integer paperId) {
        int row = paperMapper.publishPaperById(paperId);
        if (row < 1)
            return RespBean.error();
        return RespBean.success();
    }
}
